[[ This file was written Rebekah Johnson, who was one of the beta testers of Blazin' Forth. This file was donated by her to the public domain. Rebekah had never used Forth before agreeing to test this compiler for me. SDB ]]
Notes on converting "Three Examples" from Brodies "Starting Forth".
By
Rebekah Johnson
This attempts to describe some of the problems I encountered in getting the three example programs given by Leo Brodie (Chapter 12) to run in Forth-83. I hope this will help other beginners in their endeavor to learn this wonderful language. I offer this to the public domain as partial thanks to SDB for giving away such a wonderful implementation of Forth.
The most extensive changes were required in the Simple Files demo.
Example 1: Word Game
This example will work as described in Starting Forth. I took advantage of some of Blazin' Forth's features to shorten the code.
( Note: In what follows, the screen numbers refer to those in Brodies book.)
Screen #237
The definition of BL is not needed, since it is precompiled into Blazin' Forth.
I changed the value of RMARGIN to 38, to accommodate the 40 column screen of the 64. If you want to dump the output to the printer, then 78 is probably better.
I was able to dispense with the definition of LINECOUNT and the redefinition of CR by taking advantage of Blazin' Forth's system variable #OUT. This works just like Brodies LINECOUNT variable, but is much quicker. Also, Blazin' Forth resets #OUT to 0 everytime a CR is executed, which is what allows us to tighten up the code. If you wish to do this, then omit the definition of CR on line 5, and use the following:
: SPACE #OUT @ IF SPACE THEN ;
(The system will increment #OUT automatically, so 1 #OUT +! is not needed.)
: .WORD ( adr) COUNT DUP #OUT @ + RMARGIN >
IF CR ELSE SPACE THEN TYPE ;
( Once again, the system will take care of everything for us.)
Also, don't forget to replace U* in the definition of RANDOM with the Forth-83 UM* .
Example 2: Simple Filer
There are very few changes in this one, but it won't work without them. The hardest change to discover was the one involving TEXT. There are two aspects to this problem: Forth-83's TEXT leaves a count as the first byte of the text string stored, so this should be taken into account. Also, the 83 TEXT blanks the PAD up to 84 characters, which means that the definition of WHAT must be changed to:
: WHAT ( --- ADR) PAD 85 + ;
To prevent the first 4 characters of the WHAT buffer from being overwritten by TEXT. ( It took me quite a while to figure this one out.)
There are many different ways to handle the count byte difference. What I did was to simply add 1 to the address of PAD each time before moving the string somewhere else. So, for example, in Screen 241, line #2, the definition of PUT is:
: PUT ( FIELD) READ PAD 1+ ( skip count left by TEXT)
SWAP FIELD MOVE UPDATE ;
There are a few other spots like this - you shouldn't have any trouble finding them.
The next problem is in the changed definitions of NOT. You can leave most of the NOTs in place, but you must change the start flag to -1 (I used Blazin' Forth's constant TRUE, which is more readable anyway.) So, for example, the definition of FREE on screen 241 should be:
: FREE TRUE MAXRECS 0 DO I #RECORD ! RECORD C@ 33 < IF NOT LEAVE THEN
LOOP ABORT" FILE FULL" ;
You should make this change in -FIND as well.
The -TEXT in Blazin' Forth returns true if there is a match, and false otherwise. This is the exact opposite of Brodies definition, which returns true if there is no match, and false if there is a match. So you should replace all occurrences of -TEXT NOT in Brodies source with just -TEXT. For example, the phrase (in -FIND):
DUP FIELD WHAT -TEXT NOT IF
should read
DUP FIELD WHAT -TEXT IF
(This is on line 9).
There is a similar situation in (PAIR).
The final change required involves most of the words on screen #242. These words use ' which in Brodies Forth returns the Parameter field. In Forth-83, these words return the code field address. I defined an extra word, 'TABLE , which handles the conversion:
: 'TABLE ' >BODY ;
Of course, you can just redefine ' , and no further changes to the code would be needed:
: ' ' >BODY ;
Either way, you should put this before the definition of CHANGE on line 5. If you use 'TABLE, then change all occurrences of ' after that to 'TABLE. If you redefined ' then your work is done.
Example 3
You may be relieved to find out that this example works as given.